package cn.i96688.v2x.modules.netty.handler;

import java.io.ByteArrayInputStream;

import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cn.i96688.v2x.api.DataService;
import cn.i96688.v2x.modules.auth.AuthManager;
import cn.i96688.v2x.utils.MsgUtil;
import cn.i96688.v2x.v2xframe.MessageFrame;
import cn.i96688.v2x.v2xframe.Response;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

/**
 * TCP业务处理handler
 */
@ChannelHandler.Sharable
@Component
public class TcpServerHandler extends SimpleChannelInboundHandler<ByteBuf> {
	private final Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private AuthManager authManager;
	@Reference(check=false)
	private DataService dataService;
    /**
     * 使用
     * @param ctx
     * @param byteBuf
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf byteBuf) throws Exception {
    	logger.info("接收数据......");
		if (byteBuf.readableBytes() <= 2) {
			return;
		}
		try {
			int len=byteBuf.readableBytes();
			byte[] bs=new byte[len];
			byteBuf.readBytes(bs);
			MessageFrame frame=MessageFrame.decode(new ByteArrayInputStream(bs));
			
			Response resp=null;
			switch(frame.msgType) {
			//登录
			case MessageFrame.MSG_LOGIN:
				resp=authManager.login(frame.login);
				break;
			//心跳处理
			case MessageFrame.MSG_HEARTBEAT:
				resp=Response.success("ok");
				break;
			//数据接收业务处理
			case MessageFrame.MSG_SERVICE:
				//检查权限
				if(authManager.checkAuth(frame.getId())){
					//发送到业务后台	
					dataService.save(bs);
					resp=Response.success("ok");
				}else {
					//返回错误提示
					resp=Response.fail("没有登录");
				}
				break;
			}
			send2client(ctx,resp.encode());
			
		}catch(Throwable e) {
			logger.error("TCP数据接收处理出错",e);
			Response resp=Response.fail("系统错误");
			send2client(ctx,resp.encode());
		}
    }
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
    	logger.error("TCP数据接收处理出错：",cause);
    }
    /**
     * 返回消息给客户端
     * @param ctx
     * @param msg
     */
    void send2client(ChannelHandlerContext ctx, byte[] msg) {
    	ByteBuf buf=Unpooled.buffer(msg.length+1);
    	buf.writeBytes(msg);
    	buf.writeByte(MsgUtil.DELIMITER);
    	ctx.writeAndFlush(buf).addListener(future->{
    		if(!future.isSuccess()) {
    			logger.error("TCP发送给客户端消息失败");
    		}
    	});
    }
}
